#ifndef CODEVIEW_HPP
#define CODEVIEW_HPP

#include <QDockWidget>
#include <QScrollBar>
#include <QPoint>
#include <QTextBlock>
#include <QTextCursor>
#include <QTextBlockFormat>
#include <QBrush>
#include <QColor>
#include <QMap>
#include <QToolTip>

#include "command.hpp"
#include "programmanagement.hpp"
#include "textediteventhandler.hpp"
#include "tooltipeventhandler.hpp"
#include "highlighter.hpp"
#include "pix.hpp"

class Pix;

namespace Ui {
    class CodeView;
}

/**
* @brief
*
* @class CodeView codeview.hpp "codeview.hpp"
*/
class CodeView : public QDockWidget {
    Q_OBJECT
public:
    /**
    * @brief
    *
    * @fn CodeView
    * @param parent
    */
    CodeView(Pix *pix, QWidget *parent = 0);

    /**
    * @brief
    *
    * @fn ~CodeView
    */
    ~CodeView();

    /**
    * @brief
    *
    * @fn addCommands
    * @param commandList
    */
    void addCommands(const QList<Command> *commandList);

    /**
    * @brief Reset all shown GUI Elements
    *
    * @fn reset
    */
    void reset();

    void highlightLines(int p1, int p2);

protected:
    /**
    * @brief
    *
    * @fn changeEvent
    * @param e
    */
    void changeEvent(QEvent *e);

private:
    Ui::CodeView *ui;
    Pix *pix;
    TextEditEventHandler *textEditEventHandler;
    ToolTipEventHandler *tooltipEventHandler;
    Highlighter *highlighter;
    QTextBlockFormat *highlightFormat;
    QTextBlockFormat *currentLineFormat;
    QMap<QString, QString> tooltipMap;
    QMap<QString, int> anchorMap;
    bool highlightedLines;
    bool highlightedPc;
    int simulationStoppedOnLine;

    /**
    * @brief
    *
    * @fn addCommandLine
    * @param commandLine
    */
    void addCommandLine(const Command &command);

public slots:
    void onCustomHighlightingRule(QString pattern, int type);
    void onBreakpointToggled(int line, bool add);
    void onProgramCounterChanged(int pc);
    void onCustomTooltip(QString item, QString tooltip);
    void onSimulationStateChanged(bool state, int pc);
    void onJumpToBreakpoint(QString anchor);

private slots:
    void onRequestBreakpoint(QPoint point);
    void onRequestHighlightLine(QPoint point, QPoint startPoint);
    void onRequestUnHighlightLine();
    void onTooltipRequested(QPoint *point);

signals:
    void requestBreakpoint(int line);
};

#endif // CODEVIEW_HPP
